xen/common/debug.o
tools/internal/xi_restore_linux
tools/internal/xi_save_linux
+tools/internal/xi_vbd_add
+tools/internal/xi_vbd_create
+tools/internal/xi_vbd_info
+tools/internal/xi_vbd_list
+xen/drivers/scsi/BusLogic.o
TARGETS = xi_create xi_start xi_stop xi_destroy xi_build
TARGETS += xi_phys_grant xi_list xi_save_linux xi_restore_linux
TARGETS += xi_sched_global xi_sched_domain xi_usage xi_vif_params
+TARGETS += xi_vbd_create xi_vbd_add xi_vbd_list xi_vbd_info
INSTALL = $(TARGETS) xi_vifinit xi_helper
all: check-for-zlib $(TARGETS)
vdevice = device + atoi(argv[6]);
op.cmd = BLOCK_IO_OP_VBD_CREATE;
- op.u.create_info.domain = domain;
- op.u.create_info.vdevice = vdevice;
- op.u.create_info.mode = 0;
+ op.u.create_params.domain = domain;
+ op.u.create_params.vdevice = vdevice;
+ op.u.create_params.mode = 0;
if ( strchr(argv[1], 'r') )
- op.u.create_info.mode |= VBD_MODE_R;
+ op.u.create_params.mode |= VBD_MODE_R;
if ( strchr(argv[1], 'w') )
- op.u.create_info.mode |= VBD_MODE_W;
+ op.u.create_params.mode |= VBD_MODE_W;
ret = do_block_io_op(&op);
op.cmd = BLOCK_IO_OP_VBD_ADD;
- op.u.add_info.domain = domain;
- op.u.add_info.vdevice = vdevice;
+ op.u.add_params.domain = domain;
+ op.u.add_params.vdevice = vdevice;
- op.u.add_info.extent.device = device;
- op.u.add_info.extent.start_sector = atol(argv[4]);
- op.u.add_info.extent.nr_sectors = atol(argv[5]);
+ op.u.add_params.extent.device = device;
+ op.u.add_params.extent.start_sector = atol(argv[4]);
+ op.u.add_params.extent.nr_sectors = atol(argv[5]);
ret = do_block_io_op(&op);
static void io_schedule(unsigned long unused);
static int do_block_io_op_domain(struct task_struct *p, int max_to_do);
static void dispatch_rw_block_io(struct task_struct *p, int index);
-static void dispatch_probe(struct task_struct *p, int index);
static void dispatch_debug_block_io(struct task_struct *p, int index);
static void make_response(struct task_struct *p, unsigned long id,
unsigned short op, unsigned long st);
break;
case BLOCK_IO_OP_VBD_CREATE:
- /* create a new VBD for a given domain; caller must be privileged */
- if(!IS_PRIV(p))
- return -EPERM;
- ret = vbd_create(&op.u.create_info);
+ /* create a new VBD */
+ ret = vbd_create(&op.u.create_params);
break;
case BLOCK_IO_OP_VBD_ADD:
- /* add an extent to a VBD; caller must be privileged */
- if(!IS_PRIV(p))
- return -EPERM;
- ret = vbd_add(&op.u.add_info);
+ /* add an extent to a VBD */
+ ret = vbd_add(&op.u.add_params);
break;
case BLOCK_IO_OP_VBD_REMOVE:
- /* remove an extent from a VBD; caller must be privileged */
- if(!IS_PRIV(p))
- return -EPERM;
- ret = vbd_remove(&op.u.remove_info);
+ /* remove an extent from a VBD */
+ ret = vbd_remove(&op.u.remove_params);
break;
case BLOCK_IO_OP_VBD_DELETE:
- /* delete a VBD; caller must be privileged */
- if(!IS_PRIV(p))
- return -EPERM;
- ret = vbd_delete(&op.u.delete_info);
+ /* delete a VBD */
+ ret = vbd_delete(&op.u.delete_params);
+ break;
+
+ case BLOCK_IO_OP_VBD_PROBE:
+ /* query VBD information for self or others (or all) */
+ ret = vbd_probe(&op.u.probe_params);
+ if(ret == 0)
+ copy_to_user(u_block_io_op, &op, sizeof(op));
+ break;
+
+ case BLOCK_IO_OP_VBD_INFO:
+ /* query information about a particular VBD */
+ ret = vbd_info(&op.u.info_params);
break;
default:
dispatch_rw_block_io(p, i);
break;
- case XEN_BLOCK_PROBE:
- dispatch_probe(p, i);
- break;
-
case XEN_BLOCK_DEBUG:
dispatch_debug_block_io(p, i);
break;
DPRINTK("dispatch_debug_block_io: unimplemented\n");
}
-
-static void dispatch_probe(struct task_struct *p, int index)
-{
- extern void ide_probe_devices(xen_disk_info_t *xdi);
- extern void scsi_probe_devices(xen_disk_info_t *xdi);
- extern void vbd_probe_devices(xen_disk_info_t *xdi, struct task_struct *p);
-
- blk_ring_t *blk_ring = p->blk_ring_base;
- xen_disk_info_t *xdi;
- unsigned long flags, buffer;
- int rc = 0;
-
- buffer = blk_ring->ring[index].req.buffer_and_sects[0] & ~0x1FF;
-
- spin_lock_irqsave(&p->page_lock, flags);
- if ( !__buffer_is_valid(p, buffer, sizeof(xen_disk_info_t), 1) )
- {
- DPRINTK("Bad buffer in dispatch_probe_blk\n");
- spin_unlock_irqrestore(&p->page_lock, flags);
- rc = 1;
- goto out;
- }
-
- __lock_buffer(buffer, sizeof(xen_disk_info_t), 1);
- spin_unlock_irqrestore(&p->page_lock, flags);
-
- /*
- ** XXX SMH: all three of the below probe functions /append/ their
- ** info to the xdi array; i.e. they assume that all earlier slots
- ** are correctly filled, and that xdi->count points to the first
- ** free entry in the array. All kinda gross but it'll do for now.
- */
- xdi = map_domain_mem(buffer);
- xdi->count = 0;
-
- if(IS_PRIV(p)) {
- /* privileged domains always get access to the 'real' devices */
- ide_probe_devices(xdi);
- scsi_probe_devices(xdi);
- }
- vbd_probe_devices(xdi, p);
- unmap_domain_mem(xdi);
-
- unlock_buffer(p, buffer, sizeof(xen_disk_info_t), 1);
-
- out:
- make_response(p, blk_ring->ring[index].req.id, XEN_BLOCK_PROBE, rc);
-}
-
static void dispatch_rw_block_io(struct task_struct *p, int index)
{
extern void ll_rw_block(int rw, int nr, struct buffer_head * bhs[]);
#include <asm/current.h>
#include <asm/domain_page.h>
+/*
+** XXX SMH: the below probe functions /append/ their info to the
+** xdi array; i.e. they assume that all earlier slots are correctly
+** filled, and that xdi->count points to the first free entry in
+** the array. All kinda gross but it'll do for now.
+*/
+extern int ide_probe_devices(xen_disk_info_t *xdi);
+extern int scsi_probe_devices(xen_disk_info_t *xdi);
+
#if 0
#define DPRINTK(_f, _a...) printk( _f , ## _a )
/*
** Create a new VBD; all this involves is adding an entry to the domain's
-** vbd hash table.
+** vbd hash table; caller must be privileged.
*/
-long vbd_create(vbd_create_t *create_info)
+long vbd_create(vbd_create_t *create_params)
{
struct task_struct *p;
vbd_t *new_vbd, *v;
int h;
- p = find_domain_by_id(create_info->domain);
+ if(!IS_PRIV(current))
+ return -EPERM;
+
+ p = find_domain_by_id(create_params->domain);
if (!p) {
printk("vbd_create attempted for non-existent domain %d\n",
- create_info->domain);
+ create_params->domain);
return -EINVAL;
}
new_vbd = kmalloc(sizeof(vbd_t), GFP_KERNEL);
- new_vbd->vdevice = create_info->vdevice;
- new_vbd->mode = create_info->mode;
+ new_vbd->vdevice = create_params->vdevice;
+ new_vbd->mode = create_params->mode;
new_vbd->extents = (xen_extent_le_t *)NULL;
new_vbd->next = (vbd_t *)NULL;
- h = HSH(create_info->vdevice);
+ h = HSH(create_params->vdevice);
if(p->vbdtab[h]) {
for(v = p->vbdtab[h]; v->next; v = v->next)
;
** Add an extent to an existing VBD; fails if the VBD doesn't exist.
** Doesn't worry about overlapping extents (e.g. merging etc) for now.
*/
-long vbd_add(vbd_add_t *add_info)
+long vbd_add(vbd_add_t *add_params)
{
struct task_struct *p;
xen_extent_le_t *x, *xele;
vbd_t *v;
int h;
- p = find_domain_by_id(add_info->domain);
+ if(!IS_PRIV(current))
+ return -EPERM;
+
+ p = find_domain_by_id(add_params->domain);
if (!p) {
printk("vbd_add attempted for non-existent domain %d\n",
- add_info->domain);
+ add_params->domain);
return -EINVAL;
}
- h = HSH(add_info->vdevice);
+ h = HSH(add_params->vdevice);
for(v = p->vbdtab[h]; v; v = v->next)
- if(v->vdevice == add_info->vdevice)
+ if(v->vdevice == add_params->vdevice)
break;
if(!v) {
}
xele = kmalloc(sizeof(xen_extent_le_t), GFP_KERNEL);
- xele->extent.device = add_info->extent.device;
- xele->extent.start_sector = add_info->extent.start_sector;
- xele->extent.nr_sectors = add_info->extent.nr_sectors;
+ xele->extent.device = add_params->extent.device;
+ xele->extent.start_sector = add_params->extent.start_sector;
+ xele->extent.nr_sectors = add_params->extent.nr_sectors;
xele->next = (xen_extent_le_t *)NULL;
if(!v->extents) {
return 0;
}
-long vbd_remove(vbd_remove_t *remove_info)
+long vbd_remove(vbd_remove_t *remove_params)
{
+ if(!IS_PRIV(current))
+ return -EPERM;
+
return -ENOSYS;
}
-long vbd_delete(vbd_delete_t *delete_info)
+long vbd_delete(vbd_delete_t *delete_params)
+{
+ if(!IS_PRIV(current))
+ return -EPERM;
+
+ return -ENOSYS;
+}
+
+
+/*
+ * vbd_probe_devices:
+ *
+ * add the virtual block devices for this domain to a xen_disk_info_t;
+ * we assume xdi->count points to the first unused place in the array.
+ */
+static int vbd_probe_devices(xen_disk_info_t *xdi, struct task_struct *p)
+{
+ xen_extent_le_t *x;
+ xen_disk_t cur_disk;
+ vbd_t *v;
+ int i, ret;
+
+ for(i = 0; i < VBD_HTAB_SZ; i++) {
+
+ for(v = p->vbdtab[i]; v; v = v->next) {
+
+ /* SMH: don't ever expect this to happen, hence verbose printk */
+ if ( xdi->count == xdi->max ) {
+ printk("vbd_probe_devices: out of space for probe.\n");
+ return -ENOMEM;
+ }
+
+ cur_disk.device = v->vdevice;
+ cur_disk.info = XD_FLAG_VIRT | XD_TYPE_DISK;
+ if(!VBD_CAN_WRITE(v))
+ cur_disk.info |= XD_FLAG_RO;
+ cur_disk.capacity = 0 ;
+ for(x = v->extents; x; x = x->next)
+ cur_disk.capacity += x->extent.nr_sectors;
+ cur_disk.domain = p->domain;
+
+ /* Now copy into relevant part of user-space buffer */
+ if((ret = copy_to_user(xdi->disks + xdi->count, &cur_disk,
+ sizeof(xen_disk_t))) < 0) {
+ printk("vbd_probe_devices: copy_to_user failed [rc=%d]\n",
+ ret);
+ return ret;
+ }
+
+
+ xdi->count++;
+ }
+ }
+
+ return 0;
+}
+
+
+/*
+** Return information about the VBDs available for a given domain,
+** or for all domains; in the general case the 'domain' argument
+** will be 0 which means "information about the caller"; otherwise
+** the 'domain' argument will specify either a given domain, or
+** all domains ("VBD_PROBE_ALL") -- both of these cases require the
+** caller to be privileged.
+*/
+long vbd_probe(vbd_probe_t *probe_params)
+{
+ struct task_struct *p = NULL;
+ int ret;
+
+ if(probe_params->domain) {
+
+ /* we can only probe for ourselves unless we're privileged */
+ if(probe_params->domain != current->domain && !IS_PRIV(current))
+ return -EPERM;
+
+ if(probe_params->domain != VBD_PROBE_ALL) {
+
+ p = find_domain_by_id(probe_params->domain);
+
+ if (!p) {
+ printk("vbd_probe attempted for non-existent domain %d\n",
+ probe_params->domain);
+ return -EINVAL;
+ }
+
+ }
+
+ } else
+ /* default is to probe for ourselves */
+ p = current;
+
+
+ if(!p || IS_PRIV(p)) {
+
+ /* privileged domains always get access to the 'real' devices */
+ if((ret = ide_probe_devices(&probe_params->xdi))) {
+ printk("vbd_probe: error %d in probing ide devices\n", ret);
+ return ret;
+ }
+ if((ret = scsi_probe_devices(&probe_params->xdi))) {
+ printk("vbd_probe: error %d in probing scsi devices\n", ret);
+ return ret;
+ }
+ }
+
+
+ if(!p) {
+
+ u_long flags;
+
+ read_lock_irqsave (&tasklist_lock, flags);
+
+ p = &idle0_task;
+ while ( (p = p->next_task) != &idle0_task ) {
+ if (!is_idle_task(p)) {
+ if((ret = vbd_probe_devices(&probe_params->xdi, p))) {
+ printk("vbd_probe: error %d in probing virtual devices\n",
+ ret);
+ read_unlock_irqrestore(&tasklist_lock, flags);
+ return ret;
+ }
+ }
+ }
+
+ read_unlock_irqrestore(&tasklist_lock, flags);
+
+ } else {
+
+ /* probe for disks and VBDs for just 'p' */
+ if((ret = vbd_probe_devices(&probe_params->xdi, p))) {
+ printk("vbd_probe: error %d in probing virtual devices\n", ret);
+ return ret;
+ }
+
+ }
+
+
+ return 0;
+}
+
+long vbd_info(vbd_info_t *info_params)
{
return -ENOSYS;
}
}
-/*
- * vbd_probe_devices:
- *
- * add the virtual block devices for this domain to a xen_disk_info_t;
- * we assume xdi->count points to the first unused place in the array.
- */
-void vbd_probe_devices(xen_disk_info_t *xdi, struct task_struct *p)
-{
- xen_extent_le_t *x;
- vbd_t *v;
- int i;
-
- /* XXX SMH: should allow priv domains to probe vbds for other doms XXX */
-
- for(i = 0; i < VBD_HTAB_SZ; i++) {
- for(v = p->vbdtab[i]; v; v = v->next) {
-
- xdi->disks[xdi->count].device = v->vdevice;
- xdi->disks[xdi->count].info = XD_FLAG_VIRT | XD_TYPE_DISK;
-
- if(!VBD_CAN_WRITE(v))
- xdi->disks[xdi->count].info |= XD_FLAG_RO;
-
- xdi->disks[xdi->count].capacity = 0;
- for(x = v->extents; x; x = x->next)
- xdi->disks[xdi->count].capacity += x->extent.nr_sectors;
- xdi->count++;
- }
- }
-
- return;
-}
-
-void ide_probe_devices(xen_disk_info_t* xdi)
+int ide_probe_devices(xen_disk_info_t* xdi)
{
- int loop;
+ int loop, ret = 0;
unsigned int unit;
- unsigned long capacity;
- unsigned short device, type;
+ unsigned short type;
ide_drive_t *drive;
-
+ xen_disk_t cur_disk;
+
for ( loop = 0; loop < MAX_HWIFS; loop++ )
{
ide_hwif_t *hwif = &ide_hwifs[loop];
drive = &hwif->drives[unit];
if ( !drive->present ) continue;
+
+
+ /* SMH: don't ever expect this to happen, hence verbose printk */
+ if ( xdi->count == xdi->max ) {
+ printk("ide_probe_devices: out of space for probe.\n");
+ return -ENOMEM;
+ }
+
+
+ /* SMH: we export 'raw' linux device numbers to domain 0 */
+ cur_disk.device = ide_devs[(loop * MAX_DRIVES) + unit];
+
/*
** NB: we use the ide 'media' field (ide_disk, ide_cdrom, etc)
** as our 'type' field (XD_TYPE_DISK, XD_TYPE_CDROM, etc).
** Hence must ensure these are kept in sync.
*/
-
- /* SMH: we export 'raw' linux device numbers to domain 0 */
- device = ide_devs[(loop * MAX_DRIVES) + unit];
- type = drive->media;
- capacity = current_capacity(drive);
-
- xdi->disks[xdi->count].device = device;
- xdi->disks[xdi->count].info = type;
-
+ cur_disk.info = (type = drive->media);
if(type == XD_TYPE_CDROM)
- xdi->disks[xdi->count].info |= XD_FLAG_RO;
+ cur_disk.info |= XD_FLAG_RO;
- xdi->disks[xdi->count].capacity = capacity;
- xdi->count++;
+ cur_disk.capacity = current_capacity(drive);
+ cur_disk.domain = 0; /* 'physical' disks belong to domain 0
- printk("Device %d: IDE-XENO (%s) capacity %ldkB (%ldMB)\n",
- xdi->count, (type == XD_TYPE_DISK) ? "disk" :
- ((type == XD_TYPE_CDROM) ? "cdrom" : "unknown"),
- capacity>>1, capacity>>11);
+ /* Now copy into relevant part of user-space buffer */
+ if((ret = copy_to_user(xdi->disks + xdi->count, &cur_disk,
+ sizeof(xen_disk_t))) < 0) {
+ printk("ide_probe_devices: copy_to_user failed [rc=%d]\n",
+ ret);
+ return ret;
+ }
+
+ xdi->count++;
}
}
- return;
+ return ret;
}
};
-void scsi_probe_devices(xen_disk_info_t *xdi)
+int scsi_probe_devices(xen_disk_info_t *xdi)
{
Scsi_Disk *sd;
- int i;
- unsigned short device;
- unsigned long capacity;
+ xen_disk_t cur_disk;
+ int i, ret;
for ( sd = rscsi_disks, i = 0; i < sd_template.dev_max; i++, sd++ )
{
if ( sd->device == NULL ) continue;
+ /* SMH: don't ever expect this to happen, hence verbose printk */
+ if ( xdi->count == xdi->max ) {
+ printk("scsi_probe_devices: out of space for probe.\n");
+ return -ENOMEM;
+ }
+
/* SMH: we export 'raw' linux device numbers to domain 0 */
- device = scsi_devs[i];
- capacity = sd->capacity;
-
- /* XXX SMH: if make generic, need to properly determine 'type' */
- xdi->disks[xdi->count].device = device;
- xdi->disks[xdi->count].info = XD_TYPE_DISK;
- xdi->disks[xdi->count].capacity = capacity;
- xdi->count++;
-
- printk("Device %d: SCSI-XENO (disk) capacity %ldkB (%ldMB)\n",
- xdi->count, capacity>>1, capacity>>11);
+ cur_disk.device = scsi_devs[i];
+ cur_disk.info = XD_TYPE_DISK; // XXX SMH: should determine properly
+ cur_disk.capacity = sd->capacity;
+ cur_disk.domain = 0; // 'physical' disks belong to dom0
+
+ /* Now copy into relevant part of user-space buffer */
+ if((ret = copy_to_user(xdi->disks + xdi->count, &cur_disk,
+ sizeof(xen_disk_t))) < 0) {
+ printk("scsi_probe_devices: copy_to_user failed [rc=%d]\n", ret);
+ return ret;
+ }
+
+ xdi->count++;
}
- return;
+ return 0;
}
#define XEN_BLOCK_WRITE 1
#define XEN_BLOCK_READA 2
#define XEN_BLOCK_SPECIAL 4
-#define XEN_BLOCK_PROBE 5 /* get config from hypervisor */
-#define XEN_BLOCK_DEBUG 6 /* debug */
+#define XEN_BLOCK_DEBUG 5 /* debug */
/* NB. Ring size must be small enough for sizeof(blk_ring_t) <= PAGE_SIZE. */
#define BLK_RING_SIZE 64
* Information about the real and virtual disks we have; used during
* guest device probing.
*/
-#define XEN_MAX_DISK_COUNT 64
/* XXX SMH: below types chosen to align with ide_xxx types in ide.h */
#define XD_TYPE_FLOPPY 0x00
#define XD_FLAG_RO 0x40
#define XD_FLAG_VIRT 0x80
#define XD_READONLY(_x) ((_x) & XD_FLAG_RO)
-#define XD_VIRTUAL(_x) ((_x) & XF_FLAG_VIRT)
+#define XD_VIRTUAL(_x) ((_x) & XD_FLAG_VIRT)
typedef struct xen_disk
{
unsigned short device; /* device number (opaque 16 bit val) */
unsigned short info; /* device type and flags */
unsigned long capacity; /* size in terms of #512 byte sectors */
+ unsigned int domain; /* if a VBD, domain this 'belongs to' */
} xen_disk_t;
typedef struct xen_disk_info
{
- int count;
- xen_disk_t disks[XEN_MAX_DISK_COUNT];
+ /* IN variables */
+ int max; // maximumum number of disks to report
+ xen_disk_t *disks; // pointer to array of disk info
+ /* OUT variables */
+ int count; // how many disks we have info about
} xen_disk_info_t;
#endif
#define BLOCK_IO_OP_VBD_ADD 4 /* add an extent to a given VBD */
#define BLOCK_IO_OP_VBD_REMOVE 5 /* remove an extent from a given VBD */
#define BLOCK_IO_OP_VBD_DELETE 6 /* delete a VBD */
-
+#define BLOCK_IO_OP_VBD_PROBE 7 /* query VBD information for a domain */
+#define BLOCK_IO_OP_VBD_INFO 8 /* query info about a particular VBD */
typedef struct _xen_extent {
u16 device;
typedef struct _vbd_create {
- unsigned domain;
- u16 vdevice;
- u16 mode;
+ unsigned domain; // create VBD for this domain
+ u16 vdevice; // 16 bit id domain will refer to VBD as
+ u16 mode; // OR of { VBD_MODE_R , VBD_MODE_W }
} vbd_create_t;
typedef struct _vbd_add {
- unsigned domain;
- u16 vdevice;
- xen_extent_t extent;
+ unsigned domain; // domain in question
+ u16 vdevice; // 16 bit id domain refers to VBD as
+ xen_extent_t extent; // the extent to add to this VBD
} vbd_add_t;
typedef struct _vbd_remove {
- unsigned domain;
- u16 vdevice;
- xen_extent_t extent;
+ unsigned domain; // domain in question
+ u16 vdevice; // 16 bit id domain refers to VBD as
+ xen_extent_t extent; // the extent to remove from this VBD
} vbd_remove_t;
-typedef struct _vbd_delete {
- unsigned domain;
- u16 vdevice;
+typedef struct _vbd_delete {
+ unsigned domain; // domain in question
+ u16 vdevice; // 16 bit id domain refers to VBD as
} vbd_delete_t;
+#define VBD_PROBE_ALL 0xFFFFFFFF
+typedef struct _vbd_probe {
+ unsigned domain; // domain in question or VBD_PROBE_ALL
+ xen_disk_info_t xdi; // where's our space for VBD/disk info
+} vbd_probe_t;
+
+typedef struct _vbd_info {
+ unsigned domain; // domain in question
+ u16 vdevice; // 16 bit id domain refers to VBD as
+ u16 nextents; // max no. of extents to return info for
+ xen_extent_t *extents; // pointer to space for list of extents
+} vbd_info_t;
typedef struct block_io_op_st
/* no entry for BLOCK_IO_OP_SIGNAL */
/* no entry for BLOCK_IO_OP_RESET */
unsigned long ring_mfn;
- vbd_create_t create_info;
- vbd_add_t add_info;
- vbd_remove_t remove_info;
- vbd_delete_t delete_info;
+ vbd_create_t create_params;
+ vbd_add_t add_params;
+ vbd_remove_t remove_params;
+ vbd_delete_t delete_params;
+ vbd_probe_t probe_params;
+ vbd_info_t info_params;
}
u;
} block_io_op_t;
#define VBD_HTAB_SZ 16 // no. of entries in the vbd hash table.
-long vbd_create(vbd_create_t *create_info);
-long vbd_add(vbd_add_t *add_info);
-long vbd_remove(vbd_remove_t *remove_info);
-long vbd_delete(vbd_delete_t *delete_info);
+long vbd_create(vbd_create_t *create_params);
+long vbd_add(vbd_add_t *add_params);
+long vbd_remove(vbd_remove_t *remove_params);
+long vbd_delete(vbd_delete_t *delete_params);
+long vbd_probe(vbd_probe_t *probe_params);
+long vbd_info(vbd_info_t *info_params);
/* Describes a [partial] disk extent (part of a block io request) */
static blk_ring_t *blk_ring;
static unsigned int resp_cons; /* Response consumer for comms ring. */
static unsigned int req_prod; /* Private request producer. */
-static xen_disk_info_t xlblk_disk_info;
+
+#define XDI_MAX 64
+static xen_disk_info_t xlblk_disk_info; /* information about our disks/VBDs */
+
+#if 0
static int xlblk_control_msg_pending;
+#endif
+
/* We plug the I/O ring if the driver is suspended or if the ring is full. */
#define RING_PLUGGED ((BLK_RING_INC(req_prod) == resp_cons) || \
switch ( operation )
{
+#if 0
case XEN_BLOCK_PROBE:
if ( RING_PLUGGED ) return 1;
sector_number = 0;
DISABLE_SCATTERGATHER();
break;
+#endif
case XEN_BLOCK_READ:
case XEN_BLOCK_WRITE:
}
break;
+#if 0
case XEN_BLOCK_PROBE:
xlblk_control_msg_pending = bret->status;
break;
+#endif
default:
BUG();
}
+#if 0
/* Send a synchronous message to Xen. */
int xenolinux_control_msg(int operation, char *buffer, int size)
{
return xlblk_control_msg_pending ? -EINVAL : 0;
}
+#endif
static void reset_xlblk_interface(void)
{
block_io_op_t op;
- xlblk_control_msg_pending = 0;
+// xlblk_control_msg_pending = 0;
nr_pending = 0;
op.cmd = BLOCK_IO_OP_RESET;
int __init xlblk_init(void)
{
int error;
+ block_io_op_t op;
reset_xlblk_interface();
goto fail;
}
+ /* Setup our [empty] disk information structure */
+ xlblk_disk_info.max = XDI_MAX;
+ xlblk_disk_info.disks = kmalloc(XDI_MAX * sizeof(xen_disk_t), GFP_KERNEL);
+ xlblk_disk_info.count = 0;
+
/* Probe for disk information. */
- memset(&xlblk_disk_info, 0, sizeof(xlblk_disk_info));
- error = xenolinux_control_msg(XEN_BLOCK_PROBE,
- (char *)&xlblk_disk_info,
- sizeof(xen_disk_info_t));
+ memset(&op, 0, sizeof(op));
+ op.cmd = BLOCK_IO_OP_VBD_PROBE;
+ op.u.probe_params.domain = 0;
+ memcpy(&op.u.probe_params.xdi, &xlblk_disk_info, sizeof(xlblk_disk_info));
+
+ error = HYPERVISOR_block_io_op(&op);
+
if ( error )
{
printk(KERN_ALERT "Could not probe disks (%d)\n", error);
goto fail;
}
+ /* copy back the [updated] count parameter */
+ xlblk_disk_info.count = op.u.probe_params.xdi.count;
+
/* Pass the information to our virtual block device susbystem. */
xlvbd_init(&xlblk_disk_info);
}
break;
- case IOCTL_PRIVCMD_BLKMSG:
- {
- privcmd_blkmsg_t blkmsg;
- char *kbuf;
- int ret;
-
- if ( copy_from_user(&blkmsg, (void *)data, sizeof(blkmsg)) )
- return -EFAULT;
-
- if ( blkmsg.buf_size > PAGE_SIZE )
- return -EINVAL;
-
- if ( (kbuf = kmalloc(blkmsg.buf_size, GFP_KERNEL)) == NULL )
- return -ENOMEM;
-
- if ( copy_from_user(kbuf, blkmsg.buf, blkmsg.buf_size) ) {
- kfree(kbuf);
- return -EFAULT;
- }
-
- ret = xenolinux_control_msg((int)blkmsg.op, kbuf, blkmsg.buf_size);
- if ( ret != 0 ) {
- kfree(kbuf);
- return ret;
- }
-
- if ( copy_to_user(blkmsg.buf, kbuf, blkmsg.buf_size) ) {
- kfree(kbuf);
- return -EFAULT;
- }
-
- kfree(kbuf);
- }
- break;
-
default:
ret = -EINVAL;
break;